package com.design.blog.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.design.blog.dao.AdminMapper;
import com.design.blog.dao.UserinfoMapper;
import com.design.blog.model.Admin;
import com.design.blog.model.R;
import com.design.blog.model.vo.UserParams;
import com.design.blog.model.Userinfo;
import com.design.blog.service.LoginService;
import com.design.blog.utils.JWTUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @version 1.0
 * @author hxg
 * @date 2022-02-28
 *  服务实现类
 */
@Service
@Transactional
public class LoginServiceImpl  implements LoginService {
    @Resource
    private UserinfoMapper userinfoMapper;

    @Resource
    private AdminMapper adminMapper;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;


    @Override
    public R  register(UserParams params) {
        String account = params.getAccount();
        String password = params.getPassword();
        String salt = RandomUtil.randomString(5);
        if(StringUtils.isEmpty(account) ||StringUtils.isEmpty(password)){
            return R.fail(420, "账户或密码为空");
        }
        LambdaQueryWrapper<Userinfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Userinfo::getAccount, params.getAccount());
        Userinfo userinfo = userinfoMapper.selectOne(wrapper);
        if (userinfo != null) {
            return R.fail(430, "账户已存在");
        }
        Userinfo user = new Userinfo();
        user.setAccount(account);
        user.setPassword(DigestUtils.md5Hex(password+salt));
        user.setPasswordSlat(salt);
        //user.setCreateTime(new Date());
        //user.setUpdateTime(new Date());
        userinfoMapper.insert(user);

        String token = JWTUtils.createToken(user.getId());
        redisTemplate.opsForValue().set(user.getId(), token, 60,TimeUnit.MINUTES);
        cacheUserInfo(user);
        return R.success(token);
    }

    @Override
    public R login(UserParams userParams) {
        String account = userParams.getAccount();
        String password = userParams.getPassword();
        if (StringUtils.isEmpty(account) || StringUtils.isEmpty(password)) {
            return R.fail(420, "账户或密码为空");
        }
        String token;
        if (account.equals("admin")) {
            LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Admin::getAccount, account);
            wrapper.eq(Admin::getPassword,password);
            Admin admin = adminMapper.selectOne(wrapper);
            if (admin == null) {
                return R.fail(420, "账户不存在");
            }
            token = JWTUtils.createToken(admin.getId());
            redisTemplate.opsForValue().set(admin.getId(), token, 60,TimeUnit.MINUTES);
            cacheAdminInfo(admin);
        }else {
            String salt = getUerPwdSalt(account);
            if (salt == null) {
                return R.fail(4005,"账户不存在");
            }
            LambdaQueryWrapper<Userinfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Userinfo::getAccount, account);
            wrapper.eq(Userinfo::getPassword, DigestUtils.md5Hex(password+ salt));
            Userinfo user = userinfoMapper.selectOne(wrapper);
            if (user == null) {
                return R.fail(420, "账户不存在");
            }
            token = JWTUtils.createToken(user.getId());
            redisTemplate.opsForValue().set(user.getId(), token, 60,TimeUnit.MINUTES);
            cacheUserInfo(user);
        }
        return R.success(token);
    }

    @Override
    public R logout(String token) {
        Map<String, String> tokenMap = JWTUtils.checkToken(token);
        String userId = tokenMap.get("userId");
        Boolean isDelete = redisTemplate.delete(userId);
        if (isDelete) {
            return R.success("logout");
        }
        return R.fail(203,"token不合法");
    }

    private String getUerPwdSalt(String account) {
        LambdaQueryWrapper<Userinfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Userinfo::getAccount, account);
        Userinfo userinfo = userinfoMapper.selectOne(wrapper);
        if (userinfo == null) {
            return null;
        } else {
            return userinfo.getPasswordSlat();
        }
    }

    private void cacheUserInfo(Userinfo user) {
        //redis缓存用户信息 k-id v-userInfo
        Userinfo userInfoCache = new Userinfo();
        userInfoCache.setId(user.getId());
        userInfoCache.setAccount(user.getAccount());
        userInfoCache.setId(user.getIcon());
        redisTemplate.opsForValue().set(user.getId(), userInfoCache, 60,TimeUnit.MINUTES);
    }
    private void cacheAdminInfo(Admin admin) {
        //redis缓存用户信息 k-id v-userInfo
        Userinfo userInfoCache = new Userinfo();
        userInfoCache.setId(admin.getId());
        userInfoCache.setAccount(admin.getAccount());
        redisTemplate.opsForValue().set(admin.getId(), userInfoCache, 60,TimeUnit.MINUTES);
    }
}
